package cron

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/container/garray"
	"github.com/gogf/gf/v2/util/gconv"
	"reflect"
	"time"
)

type DoCronFunc func(ctx *Context) error

type JobCron struct {
	tConfig       TimeConfig
	Task          []DoCronFunc
	ctx           *Context //Task的入参
	BeginStopChan chan int //停止启动通道
	QuitChan      chan int //控制通道，有货直接退出
}

type TimeConfig struct {
	//开始时间
	BeginAt time.Time
	//间隔多久执行一次
	Interval []time.Duration
	//定时执行(暂未实现)
	Cron FixTime
}

type Context struct {
	Ctx   context.Context
	Inter interface{}
}

// FixTime 从年向秒，当出现第一个为空时（月和周除外），就代表每下一个时间开始，
// 为空之前的必须为空，之后的必须不为空
// 如MouthDay和Hour为空(WeekDay也必然为空)，就代表没Hour的几Minute几Second要func()
// 由于要配置时间年份月份对不对那些太烦了，就以一周
// 用于入参
type FixTime struct {
	WeekDay []uint
	Hour    []uint
	Minute  []uint
	Second  []uint
}

// itime 每个itime存在一个时间,是FixTime的子集
type itime struct {
	WeekDay uint
	Hour    uint
	Minute  uint
	Second  uint
}

func (f *FixTime) toITime() (t [][]uint) {
	//m 的 01234 分别对应 MWHMS

	m := make([][]uint, 0)
	val := reflect.ValueOf(*f)
	for i := 0; i < val.NumField(); i++ {
		if len(val.Field(i).Interface().([]uint)) == 0 {
			continue
		}
		gArray := garray.NewArrayFrom(gconv.Interfaces(val.Field(i).Interface().([]uint)))
		gArray.SortFunc(func(v1, v2 interface{}) bool {
			if v1.(uint) < v2.(uint) {
				return true
			} else {
				return false
			}
		})
		tempUint := make([]uint, 0)
		gArray.Iterator(func(k int, v interface{}) bool {
			tempUint = append(tempUint, v.(uint))
			return true
		})
		fmt.Println("garray", gArray)
		m = append(m, tempUint)
	}

	lens := func(i int) int { return len(m[i]) }
	for ix := make([]int, len(m)); ix[0] < lens(0); NextIndex(ix, lens) {
		var r []uint
		for j, k := range ix {
			r = append(r, m[j][k])
		}
		t = append(t, r)
		fmt.Println(r)
	}
	return
}

func NextIndex(ix []int, lens func(i int) int) {
	for j := len(ix) - 1; j >= 0; j-- {
		ix[j]++
		if j == 0 || ix[j] < lens(j) {
			return
		}
		ix[j] = 0
	}
}

//TODO:时间判断以Nanoseconds为准， 一直循环遍历，当time.Now()超过就向接口传

func ReCronIt() {

}
